package com.mkuspis.moviebrowser.activities;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.mkuspis.moviebrowser.MovieBrowserApplication;
import com.mkuspis.moviebrowser.R;
import com.mkuspis.moviebrowser.datamanagment.datamanagers.MovieDetailsDataManager;
import com.mkuspis.moviebrowser.datamanagment.models.MovieDetails;
import com.mkuspis.moviebrowser.datamanagment.models.Screenshot;
import com.mkuspis.moviebrowser.datamanagment.observer.MovieDetailsObserver;
import com.mkuspis.moviebrowser.fragments.ScreenshotsDialogFragment;
import com.mkuspis.moviebrowser.utils.DisplayMetricsUtils;

import java.util.ArrayList;

/**
 * Activity that contains and shows info about selected movie.
 */
public class MovieDetailsActivity extends SherlockFragmentActivity
        implements MovieDetailsObserver {

    public static final String MOVIE_ID_KEY = "MOVIE_ID_KEY";

    private static final String EMPTY_TRAILER = "www.youtube.com/watch?v=null";
    private static final String TRAILER_BASE_URL = "http://www.youtube.com/watch?v=";

    public int movieId;

    private Button trailerButton;
    private ProgressBar spinner;
    private ImageView poster;
    private TextView title;
    private TextView releaseDate;
    private TextView budget;
    private TextView revenue;
    private TextView runtime;
    private TextView tagline;
    private TextView cast;
    private TextView description;

    private String movieTrailerURL;
    private MovieDetails movieDetails;
    private ImageAdapter imageAdapter;

    private MovieDetailsDataManager movieDetailsDataManager;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Intent intent = getIntent();
        movieId = intent.getIntExtra(MOVIE_ID_KEY, 0);
        movieDetailsDataManager = ((MovieBrowserApplication) getApplication())
                .getMovieDetailsDataManager();

        setContentView(R.layout.activity_movie_info);

        initializeActionBar();
        initializeViewComponents();
        initScreenshotView();
    }

    @Override
    protected void onStart() {
        super.onStart();

        subscribe();
        movieDetailsDataManager.requestMovieData(movieId);
    }


    private void initializeActionBar() {
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        getSupportMenuInflater().inflate(R.menu.actionbar_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_info:
                startInfoActivity();
                break;
            case android.R.id.home:
                onBackPressed();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unscribe();
    }

    @Override
    public void subscribe() {
        movieDetailsDataManager.subscribe(this);
    }

    @Override
    public void unscribe() {
        movieDetailsDataManager.unscribe(this);
    }

    @Override
    public void onUpdateMovieDetails(final MovieDetails movieDetails) {
        this.movieDetails = movieDetails;
        setComponentsContent();
    }

    @Override
    public void onUpdateMoviePoster(final String posterLocalPath) {
        if (posterLocalPath == null) {
            poster.setImageResource(R.drawable.no_image);
        } else {
            poster.setImageURI(Uri.parse(posterLocalPath));
        }
        poster.setVisibility(View.VISIBLE);
        spinner.setVisibility(View.INVISIBLE);
    }

    @Override
    public void onUpdateMovieTrailer(final String trailerUrl) {
        this.movieTrailerURL = TRAILER_BASE_URL + trailerUrl;

        if (!movieTrailerURL.equals(EMPTY_TRAILER)) {
            trailerButton.setVisibility(View.VISIBLE);
            trailerButton.setFocusable(true);
        }
    }

    @Override
    public void onUpdateScreenshot(final Screenshot screenshot) {
        final int expectedHeight = imageAdapter.addImageFromPath(
                screenshot.getSmallPictureLocalPath());
        updateGridViewHeight(expectedHeight);
    }

    @Override
    public void onBackPressed() {
        startActivity(new Intent(this, MainActivity.class));
        super.onBackPressed();
    }

    private void startInfoActivity() {
        final Intent intent = new Intent(this, InfoActivity.class);
        startActivity(intent);
    }

    private void initializeViewComponents() {
        trailerButton = (Button) findViewById(R.id.fTrailerButton);
        trailerButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(final View view) {
                startActivity(new Intent(Intent.ACTION_VIEW,
                        Uri.parse(movieTrailerURL)));
            }
        });

        poster = (ImageView) findViewById(R.id.fPoster);
        spinner = (ProgressBar) findViewById(R.id.fImageSpinner);
        title = (TextView) findViewById(R.id.fTitle);
        releaseDate = (TextView) findViewById(R.id.fReleaseDate);
        cast = (TextView) findViewById(R.id.fCast);
        description = (TextView) findViewById(R.id.fDescription);
        budget = (TextView) findViewById(R.id.fBudget);
        revenue = (TextView) findViewById(R.id.fRevenue);
        runtime = (TextView) findViewById(R.id.fRuntime);
        tagline = (TextView) findViewById(R.id.fTagline);
    }

    private void setComponentsContent() {
        title.setText(movieDetails.getOriginalTitle());
        releaseDate.setText(movieDetails.getReleaseDate());
        cast.setText(movieDetails.getGenres());

        // --------------------------------------------
        if (movieDetails.getBudget() != 0) {
            budget.setText(String.valueOf(movieDetails.getBudget()) + "$");
        } else {
            budget.setText("no data.");
        }
        // --------------------------------------------
        if (movieDetails.getRevenue() != 0) {
            revenue.setText(String.valueOf(movieDetails.getRevenue()) + "$");
        } else {
            revenue.setText("no data.");
        }
        // --------------------------------------------
        if (movieDetails.getRuntime() == 0) {
            runtime.setText("no data.");
        } else {
            runtime.setText(movieDetails.getRuntime() + " min");
        }
        // --------------------------------------------
        if ((movieDetails.getTagline() != null) && (movieDetails.getTagline().length() != 0)) {
            tagline.setText("\"" + movieDetails.getTagline() + "\"");
        }
        // --------------------------------------------
        if (movieDetails.getOverview() == null) {
            description.setText("No Data Available.");
        } else {
            description.setText(movieDetails.getOverview());
        }
        // --------------------------------------------

        final ActionBar actionBar = getSupportActionBar();
        actionBar.setTitle(movieDetails.getOriginalTitle());
        actionBar.setDisplayShowTitleEnabled(true);
    }

    private void initScreenshotView() {
        final GridView gridView = (GridView) findViewById(R.id.gridview);
        imageAdapter = new ImageAdapter(this);
        gridView.setAdapter(imageAdapter);
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(final AdapterView<?> parent,
                                    final View view,
                                    final int position,
                                    final long id) {
                showScreenshotsFragment(imageAdapter.getImages(), position);
            }
        });
    }

    private void showScreenshotsFragment(final ArrayList<String> screenshots,
                                         final int position) {
        final ScreenshotsDialogFragment fragment = new ScreenshotsDialogFragment();

        final CharSequence movieTitle = title.getText();
        final Bundle bundle = new Bundle();
        bundle.putInt(ScreenshotsDialogFragment.POSITION, position);
        bundle.putString(ScreenshotsDialogFragment.TITLE, movieTitle == null ? null : movieTitle.toString());
        bundle.putStringArrayList(ScreenshotsDialogFragment.SCREENSHOTS, screenshots);

        fragment.setArguments(bundle);
        fragment.show(getSupportFragmentManager(), "screenshots");
    }

    private void updateGridViewHeight(final int height) {
        final GridView gridView = (GridView) findViewById(R.id.gridview);
        final ViewGroup.LayoutParams params = gridView.getLayoutParams();

        if (params != null) {
            params.height = height;
            gridView.setLayoutParams(params);
        }
    }

    private static class ImageAdapter extends BaseAdapter {
        private final Context context;
        private final ArrayList<String> images;
        private final int columns;
        private final int imageWidth;
        private final int imageHeight;
        private final int verticalSpacing;

        private ImageAdapter(final Context context) {
            this.context = context;

            images = new ArrayList<String>();
            columns = context.getResources().getInteger(R.integer.columns);
            imageWidth = context.getResources().getInteger(R.integer.image_width);
            imageHeight = context.getResources().getInteger(R.integer.image_height);
            verticalSpacing = DisplayMetricsUtils.convertDpToPixels(context,
                    context.getResources()
                            .getDimension(R.dimen.screenshots_vertical_spacing));
        }

        /**
         * Adds new item to GridView.
         *
         * @param imagePath - local path to image.
         * @return - expected height.
         */
        public int addImageFromPath(final String imagePath) {
            images.add(imagePath);
            notifyDataSetChanged();

            final int ceilHeight = imageHeight + verticalSpacing;

            return ((int) Math.ceil(images.size() / (double) columns)) * ceilHeight;
        }

        /**
         * Returns list of already added images.
         *
         * @return - list of images.
         */
        public ArrayList<String> getImages() {
            return images;
        }

        @Override
        public int getCount() {
            return images.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(final int position,
                            final View convertView,
                            final ViewGroup parent) {
            final ImageView imageView;

            if (convertView == null) {
                imageView = new ImageView(context);
                imageView.setLayoutParams(new GridView.LayoutParams(imageWidth,
                        imageHeight));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            } else {
                imageView = (ImageView) convertView;
            }

            imageView.setImageURI(Uri.parse(images.get(position)));
            return imageView;
        }
    }
}